package org.ee.system.service;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.ee.system.properties.JwtProperties;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @Author jokr
 * @Date 2025/8/19 上午11:47
 */
@Component
public class JwtProvider {
    private final Long expirationMs;
    private final Long refreshMs;
    private final SecretKey key;

    public JwtProvider(JwtProperties jwtProperties) {
        this.expirationMs = jwtProperties.getExpirationMs();
        this.key = Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes());
        this.refreshMs = jwtProperties.getRefreshMs();
    }

    /**
     * 生成token
     * @param username
     * @param extraClaims
     * @return
     */
    public String generateToken(String username, Map<String, Object> extraClaims) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + expirationMs);

        JwtBuilder builder = Jwts.builder()
                .issuer("system")  //签发者
                .subject(username)  //用户名
                .id(UUID.randomUUID().toString()) //id
                .issuedAt(new Date())
                .expiration(expiration);

        // 附加自定义字段
        if (extraClaims != null) {
            extraClaims.forEach(builder::claim);
        }

        return builder.signWith(key,Jwts.SIG.HS256).compact();

    }

    /**
     * 解析并验证 Token
     */
    public Jws<Claims> validateToken(String token) {
        return Jwts.parser()
                .verifyWith(key)
                .build()
                .parseSignedClaims(token);
    }

    /**
     * 检查是否有效
     * @param token
     * @return
     */
    public boolean validToken(String token) {
        try{
            Jwts.parser()
                    .verifyWith(key)
                    .build()
                    .parseSignedClaims(token);
            return true;
        }catch (JwtException e){
            return false;
        }
    }

    /**
     * 获取所有
     * @param token
     * @return
     */
    public Claims getAllClaimsFromToken(String token) {
        return validateToken(token).getPayload();
    }

    /**
     * 根据Key获取值
     * @param token
     * @param claimKey
     * @return
     */
    public <T> T getClaim(String token, String claimKey,Class<T> clazz) {
        Claims claims=validateToken(token).getPayload();
        return claims.get(claimKey,clazz);
    }

    /**
     * 从token获取信息
     * @param token
     * @return
     */
    public String getUsername(String token) {
        return validateToken(token).getPayload().getSubject();
    }

    /**
     * 生成refreshToken
     * @param userId
     * @return
     */
    public String refreshToken(String userId) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + refreshMs);

        JwtBuilder builder = Jwts.builder()
                .issuer("system")  //签发者
                .subject(userId)  //用户名
                .id(UUID.randomUUID().toString()) //id
                .issuedAt(new Date())
                .expiration(expiration);
        return builder.signWith(key,Jwts.SIG.HS256).compact();
    }
}
